"""
Template Manager
Handles email template management and rendering
"""

import logging
from typing import Dict, List, Any, Optional
import json
from jinja2 import Environment, BaseLoader, Template
from datetime import datetime

from services.database_manager import DatabaseManager
from config import get_config

logger = logging.getLogger(__name__)

class DatabaseTemplateLoader(BaseLoader):
    """Custom Jinja2 template loader that loads templates from database"""
    
    def __init__(self, db_manager: DatabaseManager):
        self.db_manager = db_manager
    
    def get_source(self, environment, template):
        # This would load template from database
        # For now, return None to use default templates
        return None

class TemplateManager:
    """
    Manages email templates and rendering
    """
    
    def __init__(self):
        self.config = get_config()
        self.db_manager = DatabaseManager()
        
        # Initialize Jinja2 environment
        self.jinja_env = Environment(
            loader=DatabaseTemplateLoader(self.db_manager),
            autoescape=True
        )
        
        # Default templates
        self.default_templates = self._get_default_templates()
    
    async def initialize(self):
        """Initialize template manager"""
        try:
            # Load templates from database
            await self._load_templates_from_db()
            logger.info("Template manager initialized")
        except Exception as e:
            logger.error(f"Template manager initialization failed: {e}")
            # Continue with default templates
    
    def _get_default_templates(self) -> Dict[str, Dict[str, str]]:
        """Get default email templates"""
        return {
            'welcome': {
                'subject': 'Welcome to ArXiv Subscription Platform!',
                'html': '''
                <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                        <h1 style="color: #007bff;">Welcome {{fullName}}!</h1>
                        <p>Thank you for joining the ArXiv Subscription Platform. You're now connected to the latest academic papers in your field.</p>
                        
                        <div style="background-color: white; padding: 15px; border-radius: 5px; margin: 20px 0;">
                            <h3>What's Next?</h3>
                            <ul>
                                <li>Set up your paper preferences</li>
                                <li>Configure notification settings</li>
                                <li>Explore our recommendation engine</li>
                            </ul>
                        </div>
                        
                        <p>If you have any questions, feel free to reply to this email.</p>
                        
                        <p style="margin-top: 30px;">
                            Best regards,<br>
                            The ArXiv Subscription Platform Team
                        </p>
                    </div>
                </body>
                </html>
                ''',
                'text': '''
                Welcome {{fullName}}!
                
                Thank you for joining the ArXiv Subscription Platform. You're now connected to the latest academic papers in your field.
                
                What's Next?
                - Set up your paper preferences
                - Configure notification settings
                - Explore our recommendation engine
                
                If you have any questions, feel free to reply to this email.
                
                Best regards,
                The ArXiv Subscription Platform Team
                '''
            },
            
            'daily_digest': {
                'subject': 'Your Daily ArXiv Digest - {{total_papers}} New Papers',
                'html': '''
                <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                        <h1 style="color: #007bff;">Your Daily ArXiv Digest</h1>
                        <p>Here are {{total_papers}} papers we think you'll find interesting:</p>
                        
                        {% for paper in papers %}
                        <div style="background-color: white; padding: 15px; border-radius: 5px; margin: 15px 0; border-left: 4px solid #007bff;">
                            <h3 style="margin-top: 0;"><a href="{{paper.pdf_url}}" style="color: #007bff; text-decoration: none;">{{paper.title}}</a></h3>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Authors:</strong> {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Categories:</strong> {% for category in paper.categories %}{{category}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            <p>{{paper.abstract[:300]}}{% if paper.abstract|length > 300 %}...{% endif %}</p>
                            {% if paper.reasons %}
                            <p style="font-size: 12px; color: #666; font-style: italic;">
                                Recommended because: {% for reason in paper.reasons %}{{reason}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            {% endif %}
                        </div>
                        {% endfor %}
                        
                        <div style="text-align: center; margin-top: 30px;">
                            <a href="{{platform_url}}" style="background-color: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">
                                View More Papers
                            </a>
                        </div>
                        
                        <p style="font-size: 12px; color: #666; margin-top: 30px;">
                            You're receiving this because you're subscribed to daily digests. 
                            <a href="{{unsubscribe_url}}">Unsubscribe</a> or 
                            <a href="{{preferences_url}}">change your preferences</a>.
                        </p>
                    </div>
                </body>
                </html>
                ''',
                'text': '''
                Your Daily ArXiv Digest
                
                Here are {{total_papers}} papers we think you'll find interesting:
                
                {% for paper in papers %}
                {{loop.index}}. {{paper.title}}
                Authors: {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                Categories: {% for category in paper.categories %}{{category}}{% if not loop.last %}, {% endif %}{% endfor %}
                
                {{paper.abstract[:200]}}{% if paper.abstract|length > 200 %}...{% endif %}
                
                Read more: {{paper.pdf_url}}
                
                {% endfor %}
                
                View more papers: {{platform_url}}
                
                You're receiving this because you're subscribed to daily digests. 
                Unsubscribe: {{unsubscribe_url}}
                Change preferences: {{preferences_url}}
                '''
            },
            
            'weekly_digest': {
                'subject': 'Your Weekly ArXiv Summary - {{total_papers}} Papers This Week',
                'html': '''
                <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #f8f9fa; padding: 20px; border-radius: 8px;">
                        <h1 style="color: #007bff;">Your Weekly ArXiv Summary</h1>
                        <p>Here are the top {{total_papers}} papers from this week that match your interests:</p>
                        
                        {% for paper in papers %}
                        <div style="background-color: white; padding: 15px; border-radius: 5px; margin: 15px 0; border-left: 4px solid #28a745;">
                            <h3 style="margin-top: 0;"><a href="{{paper.pdf_url}}" style="color: #007bff; text-decoration: none;">{{paper.title}}</a></h3>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Authors:</strong> {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Categories:</strong> {% for category in paper.categories %}{{category}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            <p>{{paper.abstract[:250]}}{% if paper.abstract|length > 250 %}...{% endif %}</p>
                        </div>
                        {% endfor %}
                        
                        <div style="text-align: center; margin-top: 30px;">
                            <a href="{{platform_url}}" style="background-color: #28a745; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">
                                Explore More Papers
                            </a>
                        </div>
                        
                        <p style="font-size: 12px; color: #666; margin-top: 30px;">
                            Weekly digest for {{user_email}}. 
                            <a href="{{unsubscribe_url}}">Unsubscribe</a> or 
                            <a href="{{preferences_url}}">change frequency</a>.
                        </p>
                    </div>
                </body>
                </html>
                ''',
                'text': '''
                Your Weekly ArXiv Summary
                
                Here are the top {{total_papers}} papers from this week that match your interests:
                
                {% for paper in papers %}
                {{loop.index}}. {{paper.title}}
                Authors: {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                
                {{paper.abstract[:150]}}{% if paper.abstract|length > 150 %}...{% endif %}
                
                Read: {{paper.pdf_url}}
                
                {% endfor %}
                
                Explore more: {{platform_url}}
                
                Weekly digest for {{user_email}}. 
                Unsubscribe: {{unsubscribe_url}}
                '''
            },
            
            'paper_alert': {
                'subject': 'New Papers Match Your Alert: {{alert_name}}',
                'html': '''
                <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #fff3cd; padding: 20px; border-radius: 8px; border: 1px solid #ffeaa7;">
                        <h1 style="color: #856404;">📢 Paper Alert: {{alert_name}}</h1>
                        <p>We found {{papers|length}} new papers that match your alert criteria:</p>
                        
                        {% for paper in papers %}
                        <div style="background-color: white; padding: 15px; border-radius: 5px; margin: 15px 0; border-left: 4px solid #ffc107;">
                            <h3 style="margin-top: 0;"><a href="{{paper.pdf_url}}" style="color: #007bff; text-decoration: none;">{{paper.title}}</a></h3>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Authors:</strong> {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                            </p>
                            <p style="color: #666; font-size: 14px;">
                                <strong>Published:</strong> {{paper.published_date}}
                            </p>
                            <p>{{paper.abstract[:200]}}{% if paper.abstract|length > 200 %}...{% endif %}</p>
                        </div>
                        {% endfor %}
                        
                        <div style="background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin-top: 20px;">
                            <p style="margin: 0; font-size: 14px;">
                                <strong>Alert Settings:</strong><br>
                                Name: {{alert_name}}<br>
                                Criteria: {{alert_criteria}}<br>
                                <a href="{{modify_alert_url}}">Modify this alert</a> | 
                                <a href="{{disable_alert_url}}">Disable alert</a>
                            </p>
                        </div>
                    </div>
                </body>
                </html>
                ''',
                'text': '''
                Paper Alert: {{alert_name}}
                
                We found {{papers|length}} new papers that match your alert criteria:
                
                {% for paper in papers %}
                {{loop.index}}. {{paper.title}}
                Authors: {% for author in paper.authors %}{{author}}{% if not loop.last %}, {% endif %}{% endfor %}
                Published: {{paper.published_date}}
                
                {{paper.abstract[:150]}}{% if paper.abstract|length > 150 %}...{% endif %}
                
                Read: {{paper.pdf_url}}
                
                {% endfor %}
                
                Alert Settings:
                Name: {{alert_name}}
                Criteria: {{alert_criteria}}
                
                Modify alert: {{modify_alert_url}}
                Disable alert: {{disable_alert_url}}
                '''
            },
            
            'test_email': {
                'subject': 'ArXiv Email Service Test - {{test_time}}',
                'html': '''
                <html>
                <body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                    <div style="background-color: #d4edda; padding: 20px; border-radius: 8px; border: 1px solid #c3e6cb;">
                        <h1 style="color: #155724;">✅ Email Service Test</h1>
                        <p>This is a test email from the {{service_name}}.</p>
                        
                        <div style="background-color: white; padding: 15px; border-radius: 5px; margin: 15px 0;">
                            <h3>Test Details</h3>
                            <ul>
                                <li><strong>Service:</strong> {{service_name}}</li>
                                <li><strong>Test Time:</strong> {{test_time}}</li>
                                <li><strong>Status:</strong> Email system is working correctly</li>
                            </ul>
                        </div>
                        
                        <p>If you received this email, your email configuration is working properly.</p>
                    </div>
                </body>
                </html>
                ''',
                'text': '''
                Email Service Test
                
                This is a test email from the {{service_name}}.
                
                Test Details:
                - Service: {{service_name}}
                - Test Time: {{test_time}}
                - Status: Email system is working correctly
                
                If you received this email, your email configuration is working properly.
                '''
            }
        }
    
    async def _load_templates_from_db(self):
        """Load templates from database"""
        try:
            async with self.db_manager.get_connection() as conn:
                async with conn.cursor() as cur:
                    await cur.execute("""
                        SELECT template_name, subject_template, html_template, text_template, variables
                        FROM email_templates
                        WHERE is_active = true
                    """)
                    
                    results = await cur.fetchall()
                    
                    for row in results:
                        template_name = row['template_name']
                        self.default_templates[template_name] = {
                            'subject': row['subject_template'],
                            'html': row['html_template'],
                            'text': row['text_template'],
                            'variables': json.loads(row['variables']) if row['variables'] else []
                        }
                    
                    logger.info(f"Loaded {len(results)} templates from database")
                    
        except Exception as e:
            logger.warning(f"Failed to load templates from database: {e}")
    
    async def get_template(self, template_name: str) -> Optional[Dict[str, str]]:
        """Get template by name"""
        try:
            # First try database
            async with self.db_manager.get_connection() as conn:
                async with conn.cursor() as cur:
                    await cur.execute("""
                        SELECT template_name, subject_template, html_template, text_template, variables
                        FROM email_templates
                        WHERE template_name = %s AND is_active = true
                    """, (template_name,))
                    
                    result = await cur.fetchone()
                    
                    if result:
                        return {
                            'subject': result['subject_template'],
                            'html': result['html_template'],
                            'text': result['text_template'],
                            'variables': json.loads(result['variables']) if result['variables'] else []
                        }
            
            # Fall back to default templates
            return self.default_templates.get(template_name)
            
        except Exception as e:
            logger.error(f"Failed to get template {template_name}: {e}")
            return self.default_templates.get(template_name)
    
    async def render_template(self, template_name: str, data: Dict[str, Any]) -> Dict[str, str]:
        """Render template with data"""
        try:
            template = await self.get_template(template_name)
            
            if not template:
                raise ValueError(f"Template not found: {template_name}")
            
            # Add common variables
            template_data = {
                **data,
                'platform_url': 'https://arxivsubscribe.com',  # From config
                'unsubscribe_url': f'https://arxivsubscribe.com/unsubscribe?user={data.get("user_id")}',
                'preferences_url': f'https://arxivsubscribe.com/preferences?user={data.get("user_id")}',
                'current_year': datetime.utcnow().year,
                'current_date': datetime.utcnow().strftime('%Y-%m-%d')
            }
            
            # Render templates
            rendered = {}
            
            # Render subject
            subject_template = Template(template['subject'])
            rendered['subject'] = subject_template.render(**template_data)
            
            # Render HTML
            html_template = Template(template['html'])
            rendered['html'] = html_template.render(**template_data)
            
            # Render text (if available)
            if template.get('text'):
                text_template = Template(template['text'])
                rendered['text'] = text_template.render(**template_data)
            
            return rendered
            
        except Exception as e:
            logger.error(f"Template rendering failed for {template_name}: {e}")
            raise
    
    async def list_templates(self) -> List[Dict[str, Any]]:
        """List all available templates"""
        try:
            templates = []
            
            # Get from database
            async with self.db_manager.get_connection() as conn:
                async with conn.cursor() as cur:
                    await cur.execute("""
                        SELECT template_name, variables, is_active, created_at, updated_at
                        FROM email_templates
                        ORDER BY template_name
                    """)
                    
                    results = await cur.fetchall()
                    
                    for row in results:
                        templates.append({
                            'name': row['template_name'],
                            'variables': json.loads(row['variables']) if row['variables'] else [],
                            'active': row['is_active'],
                            'source': 'database',
                            'created_at': row['created_at'].isoformat() if row['created_at'] else None,
                            'updated_at': row['updated_at'].isoformat() if row['updated_at'] else None
                        })
            
            # Add default templates not in database
            db_template_names = {t['name'] for t in templates}
            for name, template in self.default_templates.items():
                if name not in db_template_names:
                    templates.append({
                        'name': name,
                        'variables': template.get('variables', []),
                        'active': True,
                        'source': 'default',
                        'created_at': None,
                        'updated_at': None
                    })
            
            return templates
            
        except Exception as e:
            logger.error(f"Failed to list templates: {e}")
            return []
    
    async def create_template(
        self,
        template_name: str,
        subject: str,
        html_content: str,
        text_content: Optional[str] = None,
        variables: List[str] = None
    ) -> bool:
        """Create new email template"""
        try:
            async with self.db_manager.get_connection() as conn:
                async with conn.cursor() as cur:
                    await cur.execute("""
                        INSERT INTO email_templates 
                        (template_name, subject_template, html_template, text_template, variables, is_active, created_at, updated_at)
                        VALUES (%s, %s, %s, %s, %s, true, NOW(), NOW())
                        ON CONFLICT (template_name) DO UPDATE SET
                            subject_template = EXCLUDED.subject_template,
                            html_template = EXCLUDED.html_template,
                            text_template = EXCLUDED.text_template,
                            variables = EXCLUDED.variables,
                            updated_at = NOW()
                    """, (
                        template_name,
                        subject,
                        html_content,
                        text_content,
                        json.dumps(variables or [])
                    ))
            
            logger.info(f"Created/updated template: {template_name}")
            return True
            
        except Exception as e:
            logger.error(f"Failed to create template {template_name}: {e}")
            return False
    
    async def validate_template(self, template_name: str, test_data: Dict[str, Any]) -> Dict[str, Any]:
        """Validate template with test data"""
        try:
            rendered = await self.render_template(template_name, test_data)
            
            return {
                'valid': True,
                'rendered': rendered,
                'subject_length': len(rendered['subject']),
                'html_length': len(rendered['html']),
                'text_length': len(rendered.get('text', ''))
            }
            
        except Exception as e:
            return {
                'valid': False,
                'error': str(e)
            }